<?php
defined('_JEXEC') or die('Restricted access');
$joomSocialPath = JPATH_ROOT.DS.'components'.DS.'com_community';
include_once($joomSocialPath.DS.'libraries'.DS.'core.php');
require_once(JPATH_COMPONENT.DS.'libraries'.DS.'core.php' );
require_once('DTOFTUser.php');
require_once('DTOFTRouteConfig.php');
require_once('DTOFTPOIConfig.php');
require_once('DTORoute.php');
require_once('DTOLatLng.php');
require_once('DTOPoi.php');
require_once('DTOPOICategory.php');
require_once('DTOPOISubCategory.php');
require_once('DTOMyRoutesTask.php');
require_once('DTOUserRoute.php');
require_once('DTOComment.php');

class DTOFactory{
	private static $instance;
	
	public static function getInstance() 
	    {
	        if (!isset(self::$instance)) {
	            $c = __CLASS__;
	            self::$instance = new $c;
	        }
	        return self::$instance;
	}
	
	private function __construct(){
		
	}
	
	public function getDTOFTUser($object){
		$dtoFTUser=new DTOFTUser();
		$dtoFTUser->setEmail($object->email);
		$dtoFTUser->setPasswd($object->passwd);
		return $dtoFTUser;
	}
	
	public function getDTOFTRouteConfig($object){
		$dtoFTRouteConfig=new DTOFTRouteConfig();
		$dtoFTRouteConfig->setRouteFTId($object->fusionTableID);
		return $dtoFTRouteConfig;
	}
	
	public function getDTOFTPOIConfig($object){
		$dtoFTPOIConfig=new DTOFTPOIConfig();
		$dtoFTPOIConfig->setPOIFTId($object->fusionTableID);
		return $dtoFTPOIConfig;
	}
	
	private function getDTOLatLng($lngLat){
		$dtoLatLng=new DTOLatLng();
		$dtoLatLng->setLat($lngLat[1]);
		$dtoLatLng->setLng($lngLat[0]);
		return $dtoLatLng;
	}
	
	private function getDTOCoordinates($routeString){
		$routeString=preg_replace("/<LineString><coordinates>/", "", $routeString); 
		$routeString=preg_replace("/<\/coordinates><\/LineString>/", "", $routeString);
		$cells = preg_split("/ /", $routeString); 
        // Go through each cell and see if we encounter a double quote 
        foreach ($cells as $i => $value) { 
        	if($cells[$i]!=""){
        		$dtoLatLng=$this->getDTOLatLng(preg_split("/,/", $cells[$i]));
	        	$coordinates[$i]=$dtoLatLng;
        	}
    	} 
    	return $coordinates;
	}
	
	private function getDTOElevation($Elev)
	{
		return($Elev);
	}
	
	private function getDTOCoordinate($poiString){
		$poiString=preg_replace("/<Point><coordinates>/", "", $poiString); 
		$poiString=preg_replace("/<\/coordinates><\/Point>/", "", $poiString);
		$cells = preg_split("/ /", $poiString); 
        // Go through each cell and see if we encounter a double quote 
        foreach ($cells as $i => $value) { 
        	if($cells[$i]!=""){
        		$dtoLatLng=$this->getDTOLatLng(preg_split("/,/", $cells[$i]));
	        	$coordinates=$dtoLatLng;
        	}
    	} 
    	return $coordinates;
	}
	
	public function getDTOCoordinatesFromXML($xmlCoords){
		$dtoLatLng=new DTOLatLng();
		$dtoLatLng->setLat($xmlCoords->lat[0]);
		$dtoLatLng->setLng($xmlCoords->lng[0]);
		return $dtoLatLng;
	}
	
	private function getCoordinatesFromUpload(){
		//$file_string=file_get_contents($_FILES['uploadedfile']['tmp_name']);
		$parser=new SRParserGPX2LineString();
		return $parser->GPX2LineString($_FILES['uploadedfile']['tmp_name']);
	}
	
	private function getTimeForDistance($distance){
		$milliseconds = ($distance / 5.)*60*60*1000;
	
		$seconds = floor($milliseconds / 1000);
		$minutes = floor($seconds / 60);
		$hours = floor($minutes / 60);
		$days = floor($hours / 24);
		
		$minutes=$minutes-$hours*60;
		$hours=$hours-$days*24;
		
		$time="";
	
		if($days!=0){
			if($days==1)
				$time= $days." día";
			else
				$time= $days." días";
		}
		if($hours!=0){
			if($hours==1)
				$time=$time." ". $hours . " hora y";
			else
				$time=$time." ". $hours . " horas y";
		}
		$time=$time." ".$minutes." minutos";
		
		return $time;
	}
	
	private function getDistanceBetweenPoints($latitude1, $longitude1, $latitude2, $longitude2) {  
	    $earth_radius = 6371;  
	      
	    $dLat = deg2rad($latitude2 - $latitude1);  
	    $dLon = deg2rad($longitude2 - $longitude1);  
	      
	    $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);  
	    $c = 2 * asin(sqrt($a));  
	    $d = $earth_radius * $c;  
	      
	    return $d;  
	}  
	private function calculateDistance($dtoRoute){
		$distance=0;
		$coords=$dtoRoute->getCoordinates();
		if($coords!=null){
			for($i=0;$i<count($coords)-1;$i++){
				$distance=$distance+$this->getDistanceBetweenPoints($coords[$i]->getLat(), $coords[$i]->getLng(), $coords[$i+1]->getLat(), $coords[$i+1]->getLng());
			}
			$distance=round($distance,3);
		}
		return $distance;
	}
	
	public function getDTORouteFromArray($row){
		$dtoRoute=$this->getDTORouteDescFromArray($row);
		
		$dtoRoute->setCoordinates($this->getDTOCoordinates($row['route']));
		$dtoRoute->setRawCoordinates($row['route']);
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		
		return $dtoRoute;
	}
	
	public function getDTORouteFromObject($object){
		$dtoRoute=$this->getDTORouteDescFromObject($object);

		$dtoRoute->setCoordinates($this->getDTOCoordinates($object->route));
		$dtoRoute->setRawCoordinates($object->route);
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		$dtoRoute->setElevation($this->getDTOElevation($object->elevation));
		
		
		return $dtoRoute;
	}
	
	public function getDTORouteFromRequest(){
		//En este momento cogemos la información de la ruta 
		
		$dtoRoute=new DTORoute();
		$dtoRoute->setId(JRequest::getVar('id', null));
		$dtoRoute->setUser(CFactory::getUser());
		$dtoRoute->setName(JRequest::getVar('routeName', ""));
		$dtoRoute->setDescription(JRequest::getVar('routeDescrip', ""));
		$dtoRoute->setCoordinates($this->getDTOCoordinates(JRequest::getVar('route', 0)));
		$dtoRoute->setRawCoordinates("<LineString><coordinates>".JRequest::getVar('route', 0)."</coordinates></LineString>");
		$dtoRoute->setDistance(JRequest::getVar('distance', 0));
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		$dtoRoute->setElevation(JRequest::getVar('elevation', "11"));
		
		return $dtoRoute;
	}
	
	public function getDTORouteFromJoin($name,$description,$coordinates){
		//En este momento cogemos la información de la ruta 
		
		$dtoRoute=new DTORoute();
		$dtoRoute->setId(JRequest::getVar('id', null));
		$dtoRoute->setUser(CFactory::getUser());
		$dtoRoute->setName($name);
		$dtoRoute->setDescription($description);
		$dtoRoute->setCoordinates($coordinates);
		$dtoRoute->setRawCoordinates("<LineString><coordinates>".$coordinates."</coordinates></LineString>");
		$dtoRoute->setDistance(JRequest::getVar('distance', 0));
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		$dtoRoute->setElevation(JRequest::getVar('elevation', "11"));
		
		return $dtoRoute;
	}
	
	public function getDTORouteFromUpload(){
		$dtoRoute=new DTORoute();
		$dtoRoute->setId(JRequest::getVar('id', null));
		$dtoRoute->setUser(CFactory::getUser());
		$dtoRoute->setName(JRequest::getVar('routeName', ""));
		$dtoRoute->setDescription(JRequest::getVar('routeDescrip', ""));
		$dtoRoute->setRawCoordinates($this->getCoordinatesFromUpload());
		$dtoRoute->setCoordinates($this->getDTOCoordinates($dtoRoute->getRawCoordinates()));
		$dtoRoute->setDistance($this->calculateDistance($dtoRoute));
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		
		return $dtoRoute;
	}
	
	public function getDTORouteDescFromArray($row){
		$dtoRoute=new DTORoute();
		$dtoRoute->setId($row['id']);
        $dtoRoute->setUser(CFactory::getUser($row['userID']));
		$dtoRoute->setName($row['name']);
		$dtoRoute->setDescription($row['description']);
		$dtoRoute->setDistance($row['distance']);
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		
		return $dtoRoute;
	}
	
	public function getDTORouteDescFromObject($object){
		$dtoRoute=new DTORoute();
		$dtoRoute->setId($object->id);
        $dtoRoute->setUser(CFactory::getUser($object->userID));
		$dtoRoute->setName($object->name);
		$dtoRoute->setDescription($object->description);
		$dtoRoute->setDistance($object->distance);
		$dtoRoute->setTime($this->getTimeForDistance($dtoRoute->getDistance()));
		
		return $dtoRoute;
	}
	
	public function getDTORoutesDescFromObject($rows){
		$dtoRoutes=array();
		foreach ($rows as $row) {
			$dtoRoutes[]=$this->getDTORouteDescFromObject($row);
		}
		return $dtoRoutes;
	}
	
	public function getDTORoutesDescFromArray($rows){
		$dtoRoutes=array();
		foreach ($rows as $row) {
			$dtoRoutes[]=$this->getDTORouteDescFromArray($row);
		}
		return $dtoRoutes;
	}
	
	private function getLatitudeFromRaw($lngLat){
		$lngLat=preg_replace("/<Point><coordinates>/", "", $lngLat); 
		$lngLat=preg_replace("/<\/coordinates><\/Point>/", "", $lngLat);
		$lngLat = preg_split("/,/", $lngLat);
        return $lngLat[1];
	}
	
	private function getLongitudeFromRaw($lngLat){
		$lngLat=preg_replace("/<Point><coordinates>/", "", $lngLat); 
		$lngLat=preg_replace("/<\/coordinates><\/Point>/", "", $lngLat);
		$lngLat = preg_split("/,/", $lngLat);
        return $lngLat[0];
	}
	
	public function getDTOPOIFromRequest(){
		$dtoPOI=new DTOPoi();
		$dtoPOI->setId(JRequest::getVar('id', 0));
		$dtoPOI->setRoute(JRequest::getVar('routeID', 0));
		$dtoPOI->setName(JRequest::getVar('name', 'null'));
		$dtoPOI->setDescription(JRequest::getVar('descrip', 'null','get','none',JREQUEST_ALLOWHTML));
		$dtoPOI->setRawLocation("<Point><coordinates>".JRequest::getVar('position', 0)."</coordinates></Point>");
		$dtoPOI->setLocation($this->getDTOCoordinate($dtoPOI->getRawLocation()));
		$dtoPOI->setSubCategory(JRequest::getVar('subCategory', 0));
		return $dtoPOI;
	}
	
	public function getDTOPOIsFromObject($rawPOIs){
		$pois=array();
		foreach($rawPOIs as $rawPoi){
			$dtoPOI=new DTOPoi();
			$dtoPOI->setId($rawPoi->id);
			$dtoPOI->setName($rawPoi->name);
			$dtoPOI->setDescription($rawPoi->description);
			$dtoLatLng=new DTOLatLng();
			$dtoLatLng->setLat($this->getLatitudeFromRaw($rawPoi->location));
			$dtoLatLng->setLng($this->getLongitudeFromRaw($rawPoi->location));
			$dtoPOI->setLocation($dtoLatLng);
		    $dtoPOI->setRoute($rawPoi->routeID);
			$dtoPOI->setSubCategory($rawPoi->subCategoryID);
			
			$pois[]=$dtoPOI;
		}
		return $pois;
	}
	
	public function getDTOPOIsFromArray($rawPOIs){
		$pois=array();
		foreach($rawPOIs as $rawPoi){
			$dtoPOI=new DTOPoi();
			$dtoPOI->setId($rawPoi['id']);
			$dtoPOI->setName($rawPoi['name']);
			$dtoPOI->setDescription($rawPoi['description']);
			$dtoLatLng=new DTOLatLng();
			$dtoLatLng->setLat($this->getLatitudeFromRaw($rawPoi['location']));
			$dtoLatLng->setLng($this->getLongitudeFromRaw($rawPoi['location']));
			$dtoPOI->setLocation($dtoLatLng);
			$dtoPOI->setRawLocation($rawPoi['location']);
		    $dtoPOI->setRoute($rawPoi['routeID']);
			$dtoPOI->setSubCategory($rawPoi['subCategoryID']);
			
			$pois[]=$dtoPOI;
		}
		return $pois;
	}
	
	public function getDTOPOISubCategory($object){
		$dtoPOISubCategory=new DTOPOISubCategory();
		
		$dtoPOISubCategory->setId($object->id);
		$dtoPOISubCategory->setName($object->name);
		$dtoPOISubCategory->setDescription($object->description);
		$dtoPOISubCategory->setImage($object->image);
		$dtoPOISubCategory->setCategory($object->idCategory);
		return $dtoPOISubCategory;
	}
	
	public function getDTOPOISubCategories($objectList){
		$dtoSubCategories=array();
		foreach ($objectList as $object) {
			$dtoSubCategories[]=$this->getDTOPOISubCategory($object);
		}
		return $dtoSubCategories;
	}
	
	public function getDTOPOICategory($object){
		$dtoPOICategory=new DTOPOICategory();
		
		$dtoPOICategory->setId($object->id);
		$dtoPOICategory->setName($object->name);
		$dtoPOICategory->setDescription($object->description);
		return $dtoPOICategory;
	}
	
	public function getDTOPOICategories($objectList){
		$dtoCategories=array();
		foreach ($objectList as $object) {
			$dtoCategories[]=$this->getDTOPOICategory($object);
		}
		return $dtoCategories;
	}
	
	public function getDTOMyRoutesTaskCreador($dtoRoute){
		$option=JRequest::getCMD('option');
		$dtoMyRoutesTask=new DTOMyRoutesTask();
		
		$dtoMyRoutesTask->setTask(null);
		$dtoMyRoutesTask->setLink(null);
		$dtoMyRoutesTask->setImg('components'.DS.$option.DS.'images'.DS.'User.png');		
		$dtoMyRoutesTask->setImgTitle(JText::_('MYROUTESTASK_CREATOR'));
		return $dtoMyRoutesTask;
	}
	
	public function getDTOMyRoutesTaskAdd($dtoRoute){
		$option=JRequest::getCMD('option');
		$dtoMyRoutesTask=new DTOMyRoutesTask();
		
		$dtoMyRoutesTask->setTask("add");
		$dtoMyRoutesTask->setLink(JRoute::_('index.php?option=' . $option .'&task=addUserRoute&id=' . $dtoRoute->getId().'&view=default&format=raw'));
		$dtoMyRoutesTask->setImg('components'.DS.$option.DS.'images'.DS.'Add.png');		
		$dtoMyRoutesTask->setImgTitle(JText::_('MYROUTESTASK_ADD'));
		return $dtoMyRoutesTask;
	}
	
	public function getDTOMyRoutesTaskRemove($dtoRoute){
		$option=JRequest::getCMD('option');
		$dtoMyRoutesTask=new DTOMyRoutesTask();
		
		$dtoMyRoutesTask->setTask("remove");
		$dtoMyRoutesTask->setLink(JRoute::_('index.php?option=' . $option .'&task=removeUserRoute&id=' . $dtoRoute->getId().'&view=default&format=raw'));
		$dtoMyRoutesTask->setImg('components'.DS.$option.DS.'images'.DS.'Remove.png');		
		$dtoMyRoutesTask->setImgTitle(JText::_('MYROUTESTASK_DELETE'));
		return $dtoMyRoutesTask;
	}
	
	public function getDTOUserRoutes($rows){
		$dtoUserRoutes=array();
		foreach ($rows as $row) {
			$dtoUserRoute=new DTOUserRoute();
			$dtoUserRoute->setId($row->id);
			$dtoUserRoute->setUserId($row->userID);
			$dtoUserRoute->setRouteId($row->routeID);
			$dtoUserRoutes[]=$dtoUserRoute;
		}
		return $dtoUserRoutes;
	}
	
	public function getDTOComments($rows){
		$dtoComments=array();
		foreach ($rows as $row) {
			$dtoComment=new DTOComment();
			$dtoComment->setId($row->id);
			$dtoComment->setDate($row->commentDate);
			$dtoComment->setText($row->commentText);
			$dtoComment->setRouteID($row->routeID);
			$dtoComment->setUser(CFactory::getUser($row->userID));
			
			$dtoComments[]=$dtoComment;
		}
		return $dtoComments;
	}
	
}

?>